/*`
 * vim:ts=8:sw=3:sts=8:noexpandtab:cino=>5n-3f0^-2{2
 */

#include "e_mod_main.h"
#include "e_mod_config.h"

# define D(x)  do {printf(__FILE__ ":%d:  ", __LINE__); printf x; fflush(stdout);} while (0)

/***************************************************************************/
/**/
static Eloquence *_eloquence_new(Evas *e);
static void _button_cb_mouse_down(void *data, Evas *e, Evas_Object *obj, void *event_info);
static void _eloquence_shutdown(Eloquence *eloquence);
static void _eloquence_config_menu_new(Eloquence *eloquence);

static Eloquence_Face *_eloquence_face_new();
static void _eloquence_face_free(Eloquence_Face *face);
static void _eloquence_face_enable(Eloquence_Face *face);
static void _eloquence_face_disable(Eloquence_Face *face);
static void  _eloquence_face_menu_new(Eloquence_Face *face);

static void _eloquence_face_cb_menu_configure(Eloquence_Face *face, 
		E_Menu *m, E_Menu_Item *mi);

static void _eloquence_face_cb_mouse_down(Eloquence_Face *face, 
		Evas *e, Evas_Object *obj, void *event_info);


static void _eloquence_face_cb_pre_menu_control(Eloquence_Face *face, E_Menu *menu);
static void _eloquence_face_cb_post_menu_control(Eloquence_Face *face, E_Menu *menu);
static void _control_menu_load(E_Menu *menu, Eloquence_Face *face);

static int _eloquence_face_switch_theme(Eloquence_Face *face, const char *theme);
static void _eloquence_face_switch_player(Eloquence_Face *face);

static void callback_player_play_pause(Eloquence_Face *face, Evas_Object *obj, 
				const char *emission, const char *source);
static void callback_player_track_next(Eloquence_Face *face, Evas_Object *obj, 
				const char *emission, const char *source);
static void callback_player_track_prev(Eloquence_Face *face, Evas_Object *obj, 
				const char *emission, const char *source);
static void callback_player_vol_inc(Eloquence_Face *face, Evas_Object *obj, 
				const char *emission, const char *source);
static void callback_player_vol_dec(Eloquence_Face *face, Evas_Object *obj, 
				const char *emission, const char *source);
static void callback_player_shuffle(Eloquence_Face *face, Evas_Object *obj, 
				const char *emission, const char *source);
static void callback_gui_menu(Eloquence_Face *face, Evas_Object *obj, 
				const char *emission, const char *source);

static void _menu_cb_post(void *data, E_Menu *m);


/* gadcon requirements */
static E_Gadcon_Client *_gc_init(E_Gadcon *gc, const char *name, const char *id, 
				const char *style);
static void _gc_shutdown(E_Gadcon_Client *gcc);
static void _gc_orient(E_Gadcon_Client *gcc);
static char *_gc_label(void);
static Evas_Object *_gc_icon(Evas *evas);

static E_Module *eloquence_module = NULL;


/* and actually define the gadcon class that this module provides (just one) */
static const E_Gadcon_Client_Class _gadcon_class = {  
   GADCON_CLIENT_CLASS_VERSION,
     "Eloquence",
     {
        _gc_init, _gc_shutdown, _gc_orient, _gc_label, _gc_icon
     }
};

static E_Gadcon_Client *
_gc_init(E_Gadcon *gc, const char *name, const char *id, const char *style) {
   Evas_Object *o;
   E_Gadcon_Client *gcc;
   Instance *inst;
   Eloquence *eloquence;

   inst = E_NEW(Instance, 1);

   eloquence = _eloquence_new(gc->evas);

   gcc = e_gadcon_client_new(gc, name, id, style, eloquence->face->eloquence_object);
   
   gcc->data = inst;
   
   inst->gcc = gcc;
   inst->o_eloquence = eloquence->face->eloquence_object;
   inst->main_menu = eloquence->config_menu;
   e_gadcon_client_util_menu_attach(gcc);
   evas_object_event_callback_add(inst->o_eloquence, EVAS_CALLBACK_MOUSE_DOWN,
				  _button_cb_mouse_down, inst);

	 eloquence->face->inst = inst;
   return gcc;
}
    
static void
_gc_shutdown(E_Gadcon_Client *gcc) { 
   Instance *inst;
   
   inst = gcc->data;
   if (inst->main_menu) {
			 e_menu_post_deactivate_callback_set(inst->main_menu, NULL, NULL);
			 e_object_del(E_OBJECT(inst->main_menu));
			 inst->main_menu = NULL;
	 }
   evas_object_del(inst->o_eloquence);
   free(inst);
}
    
static void
_gc_orient(E_Gadcon_Client *gcc) {
   Instance *inst;
   
   inst = gcc->data;
   e_gadcon_client_aspect_set(gcc, 16, 16);
   e_gadcon_client_min_size_set(gcc, 2500, 16);
}
   
static char *
_gc_label(void) {
   return _("Eloquence");
}

static Evas_Object *
_gc_icon(Evas *evas) {
   Evas_Object *o;
   char buf[4096];
   
   o = edje_object_add(evas);
   snprintf(buf, sizeof(buf), "%s/module.eap",
	    e_module_dir_get(eloquence_module));
   edje_object_file_set(o, buf, "icon");
   return o;
}




/* Module specific private routines */
static int _eloquence_count;

static E_Config_DD *conf_edd;
static E_Config_DD *conf_face_edd;

void _eloquence_face_cb_config_updated(Eloquence_Face *face) {
D(("!!! config updated1\n"));
	_eloquence_face_switch_theme( face, face->conf->theme);
D(("!!! config updated2\n"));
	_eloquence_face_switch_player(face);
}




/* module private routines */
static Eloquence *
_eloquence_new(Evas *e)
{
   Eloquence *eloquence;
   Evas_List *managers, *l, *l2, *cl;
   E_Menu_Item *mi;

   _eloquence_count = 0;
   eloquence = E_NEW(Eloquence, 1);
   if (!eloquence) return NULL;

   conf_face_edd = E_CONFIG_DD_NEW("Eloquence_Config_Face", Config_Face);
#undef T
#undef De
#define T Config_Face
#define De conf_face_edd
   E_CONFIG_VAL(De, T, enabled, UCHAR);
   E_CONFIG_VAL(De, T, allow_overlap, INT);
   E_CONFIG_VAL(De, T, theme, STR);
   E_CONFIG_VAL(De, T, player, INT);
   E_CONFIG_VAL(De, T, poll_time, DOUBLE);
   E_CONFIG_VAL(De, T, input_charset, STR);

   conf_edd = E_CONFIG_DD_NEW("Eloquence_Config", Config);
#undef T
#undef De
#define T Config
#define De conf_edd
  E_CONFIG_LIST(De, T, faces, conf_face_edd);

   eloquence->conf = e_config_domain_load("module.eloquence", conf_edd);
   if (!eloquence->conf) {
	   eloquence->conf = E_NEW(Config, 1);
   }
   
   _eloquence_config_menu_new(eloquence);
   cl = eloquence->conf->faces; 

	     Eloquence_Face *face;

	     face = _eloquence_face_new();
	     if (face) {
		     face->eloquence = eloquence;
		     eloquence->faces = evas_list_append(eloquence->faces, face);
		     if (!cl) {

			     face->conf = E_NEW(Config_Face, 1);
			     face->conf->enabled = 1;
			     face->conf->allow_overlap = 0;
			     face->conf->poll_time = 8.0;
			     face->conf->theme = evas_stringshare_add(THEME_DEFAULT);

#ifdef HAVE_BMP_XMMSCTRL_H
			     face->conf->player = PLAYER_XMMS;
#endif
#ifdef HAVE_BMP_BEEPCTRL_H
			     face->conf->player = PLAYER_BMP;
#endif
#ifdef HAVE_BMPX_METADATA_H
			     face->conf->player = PLAYER_BMPX;
#endif
#ifdef HAVE_AUDACIOUS_BEEPCTRL_H
			     face->conf->player = PLAYER_AUDACIOUS;
#endif
#ifdef HAVE_LIBMPD_LIBMPDCLIENT_H
			     face->conf->player = PLAYER_MPD;
#endif
#ifdef HAVE_AMAROK
			     face->conf->player = PLAYER_AMAROK;
#endif

#ifdef HAVE_XMMSCLIENT_XMMSCLIENT_H
			     face->conf->player = PLAYER_XMMS2;
#endif
			     face->conf->input_charset = evas_stringshare_add(CHARSET_DEFAULT);
			     eloquence->conf->faces = evas_list_append(
					     eloquence->conf->faces, face->conf);
		     }
		     else {
			     face->conf = cl->data;
			     cl = cl->next;
		     }
		     E_CONFIG_LIMIT(face->conf->poll_time, 0.1, 10.0);
		     E_CONFIG_LIMIT(face->conf->allow_overlap, 0, 1);

		     _eloquence_face_menu_new(face);

				 eloquence->config_menu = face->menu;
				 face->evas = e;

				 _eloquence_face_switch_theme(face, face->conf->theme);

				 eloquence->face = face;
		     _eloquence_face_switch_player(face);
	    }
	 eloquence->module = eloquence;
   return eloquence;
}




static void
_eloquence_shutdown(Eloquence *eloquence) {
   Evas_List *list;

   E_CONFIG_DD_FREE(conf_edd);
   E_CONFIG_DD_FREE(conf_face_edd);

   for (list = eloquence->faces; list; list = list->next){
	   Eloquence_Face *face = list->data;
	   ecore_timer_del(face->update_timer);
#ifdef HAVE_AMAROK
     if (face->conf->player == PLAYER_AMAROK)
		   amarok_free(face);
#endif
	   _eloquence_face_free(list->data);
   }
   evas_list_free(eloquence->faces);

   e_object_del(E_OBJECT(eloquence->config_menu));


     
   evas_list_free(eloquence->conf->faces);
   free(eloquence->conf);
   free(eloquence);
}

static void
_eloquence_config_menu_new(Eloquence *eloquence) {
   eloquence->config_menu = e_menu_new();
}

static Eloquence_Face * _eloquence_face_new() {
   Eloquence_Face *face;
   Evas_Object *o;

   face = E_NEW(Eloquence_Face, 1);
   if (!face) return NULL;

   return face;
}

static void
_eloquence_face_free(Eloquence_Face *face) {
   if (face->update_timer)
	   ecore_timer_del(face->update_timer);


   if (face->eloquence_object)
      evas_object_del(face->eloquence_object);
   if (face->event_object)
      evas_object_del(face->event_object);

   e_object_del(E_OBJECT(face->menu));

   if (face->conf->theme)
	   evas_stringshare_del(face->conf->theme);
   
   free(face->conf);
   free(face);

   _eloquence_count--;
}

static void
_eloquence_face_enable(Eloquence_Face *face) {
   face->conf->enabled = 1;

   if (face->eloquence_object)
      evas_object_show(face->eloquence_object);
   if (face->event_object)
      evas_object_show(face->event_object);

   e_config_save_queue();
}

static void
_eloquence_face_disable(Eloquence_Face *face) {
   face->conf->enabled = 0;

   if (face->eloquence_object)
      evas_object_hide(face->eloquence_object);
   if (face->event_object)
      evas_object_hide(face->event_object);

   e_config_save_queue();
}

static void
_eloquence_face_menu_new(Eloquence_Face *face) {
   E_Menu *mn, *smn;
   E_Menu_Item *mi;
   mn = e_menu_new();
   face->menu = mn;

   mi = e_menu_item_new(mn);
   e_menu_item_label_set(mi, _("Configuration"));
	 e_util_menu_item_edje_icon_set(mi, "enlightenment/configuration");
	 e_menu_item_callback_set(mi, _eloquence_face_cb_menu_configure, face);


   smn = e_menu_new();
   e_menu_pre_activate_callback_set(smn, _eloquence_face_cb_pre_menu_control, face);
   e_menu_post_deactivate_callback_set(smn, _eloquence_face_cb_post_menu_control, face);
   
   face->control_menu = smn;
   mi = e_menu_item_new(mn);
   e_menu_item_label_set(mi, _("Control Player"));
   e_menu_item_submenu_set(mi, face->control_menu);

	 mi = e_menu_item_new(mn);
	 e_menu_item_separator_set(mi, 1);
}

static void
_eloquence_face_cb_menu_configure(Eloquence_Face *face, E_Menu *m, E_Menu_Item *mi) {
	  if (!face) return;
	  _config_eloquence_module(NULL, face->eloquence);
}

static void
_eloquence_face_cb_mouse_down(Eloquence_Face *face, Evas *e, Evas_Object *obj, void *event_info) {
	/* We just don't use it here and catch all mouse-clicks with the edje */	
}

void draw_text(Eloquence_Face *face) {
  size_t insize = (strlen(face->song))+1;
  size_t avail = insize+2;

   face->song_utf8 = face->outbuf;
   size_t iconv_errorcode = iconv(face->cd, &face->song, &insize, &face->song_utf8, &avail);
   edje_object_part_text_set(face->eloquence_object, "title", face->outbuf);
}

static void _eloquence_face_cb_pre_menu_control(Eloquence_Face *face, E_Menu *menu) {
  if (menu->realized || !face)
	  return;
  // generate menu
  _control_menu_load(menu, face);
}

static void _eloquence_face_cb_post_menu_control(Eloquence_Face *face, E_Menu *menu) {
  if (menu->parent_item && menu->parent_item->active)
	  return;
  // remove all menuitems
  Evas_List *items;
  for (items = menu->items; items; items = items->next)
	  e_object_del(E_OBJECT(items->data));
  evas_list_free(menu->items);
  menu->items = NULL;
}

static void _control_menu_load(E_Menu *menu, Eloquence_Face *face) {
   switch (face->conf->player)
     {
#ifdef HAVE_XMMS_XMMSCTRL_H
				case PLAYER_XMMS:
					xmms_init_menu(menu, face);
					break;	      
#endif
#ifdef HAVE_XMMSCLIENT_XMMSCLIENT_H
				case PLAYER_XMMS2:
					xmms2_init_menu(menu, face);
					break;
#endif
#ifdef HAVE_BMP_BEEPCTRL_H
				case PLAYER_BMP:
					bmp_init_menu(menu, face);
					break;	      
#endif
#ifdef HAVE_BMPX_METADATA_H
				case PLAYER_BMPX:
					bmpx_init_menu(menu, face);
					break;	      
#endif
#ifdef HAVE_AUDACIOUS_BEEPCTRL_H
				case PLAYER_AUDACIOUS:
	 				audacious_init_menu(menu, face);
         	break;	      
#endif
#ifdef HAVE_AMAROK
				case PLAYER_AMAROK:
					amarok_init_menu(menu, face);
					break;	      
#endif
#ifdef HAVE_LIBMPD_LIBMPDCLIENT_H
				case PLAYER_MPD:
					mpd_connect(face);
					mpd_init_menu(menu, face);
					break;	      
#endif
     }
}




static int
_eloquence_face_switch_theme(Eloquence_Face *face, const char *theme) {
   Evas_Object *o;

   face->cd = iconv_open ("UTF-8", face->conf->input_charset);

   char path[PATH_MAX] = PACKAGE_DATA_DIR"/themes/";
   strcat(strcat(path, theme), ".edj");

   o = edje_object_add(face->evas);
   
   if ( edje_object_file_set(o, path, "eloquence/main") )
   {
	   printf("1 Eloquence: Theme set to %s\n",path);
	   if (face->eloquence_object)
		   evas_object_del(face->eloquence_object);

	   // don't free if old and new are the same piece of memory (like on startup)
	   if (face->conf->theme != theme){
		   if (face->conf->theme)
			   evas_stringshare_del(face->conf->theme);
		   face->conf->theme = evas_stringshare_add(theme);
	   }

	   face->eloquence_object = o;

	   edje_object_signal_callback_add(o, "pause", "pause", callback_player_play_pause, face);
	   edje_object_signal_callback_add(o, "next", "next", callback_player_track_next, face);
	   edje_object_signal_callback_add(o, "prev", "prev", callback_player_track_prev, face);
	   edje_object_signal_callback_add(o, "inc_vol", "inc_vol", callback_player_vol_inc, face);
	   edje_object_signal_callback_add(o, "dec_vol", "dec_vol", callback_player_vol_dec, face);
	   edje_object_signal_callback_add(o, "shuffle", "shuffle", callback_player_shuffle, face);
     edje_object_signal_callback_add(o, "options", "options", callback_gui_menu, face);
	   
	   if (face->conf->enabled){
				 evas_object_show(o);
				 printf("Eloquence: 3 face enabled\n");
		 }
	   if (!face->event_object){ // no need to recreate
				 o = evas_object_rectangle_add(face->evas);
				 face->event_object = o;
				 evas_object_layer_set(o, 2);
				 evas_object_repeat_events_set(o, 1);
				 evas_object_color_set(o, 0, 0, 0, 0);
				 
				 if (face->conf->enabled)
						 evas_object_show(o);
	   }
	   
	   int w, h;
	   edje_object_size_min_get(o, &w, &h);
	   
	   e_config_save_queue();
   }
   else{  // unable to open theme, keep current
			 printf("Eloquence: Theme not found\n");
			 evas_object_del(o);
			 o = NULL;
   }
   return o != NULL;
}




static void
_eloquence_face_switch_player(Eloquence_Face *face) {
   if(face->update_timer)
	     ecore_timer_del(face->update_timer);

#ifdef HAVE_LIBMPD_LIBMPDCLIENT_H
   if (face->old_player == PLAYER_MPD)
	   mpd_disconnect(face);
#endif
#ifdef HAVE_AMAROK
   if (face->old_player == PLAYER_AMAROK)
	   amarok_free(face);
#endif

   switch (face->conf->player)
     {
#ifdef HAVE_XMMS_XMMSCTRL_H
				case PLAYER_XMMS:
					face->update_timer = ecore_timer_add(
											face->conf->poll_time, 
											xmms_update_song, face);
					break;	      
#endif
#ifdef HAVE_XMMSCLIENT_XMMSCLIENT_H
				case PLAYER_XMMS2:
					xmms2_connect(face);
					face->update_timer = ecore_timer_add(
									face->conf->poll_time, 
									xmms2_update_song, face);
					break;
#endif
#ifdef HAVE_BMP_BEEPCTRL_H
				case PLAYER_BMP:
					face->update_timer = ecore_timer_add(
									face->conf->poll_time, 
									bmp_update_song, face);
					break;	      
#endif
#ifdef HAVE_BMPX_METADATA_H
				case PLAYER_BMPX:
					face->update_timer = ecore_timer_add(
									face->conf->poll_time, 
									bmpx_update_song, face);
					break;	      
#endif
#ifdef HAVE_AUDACIOUS_BEEPCTRL_H
				case PLAYER_AUDACIOUS:
					face->update_timer = ecore_timer_add(
										face->conf->poll_time, 
										audacious_update_song, face);
					break;	      
#endif
#ifdef HAVE_AMAROK
				case PLAYER_AMAROK:
					amarok_init(face);
					face->update_timer = ecore_timer_add(
							face->conf->poll_time, 
							amarok_update_song, face);
					break;	      
#endif
#ifdef HAVE_LIBMPD_LIBMPDCLIENT_H
				case PLAYER_MPD:
					mpd_connect(face);
					face->update_timer = ecore_timer_add(
							face->conf->poll_time, 
							mpd_update_song, face);
					break;	      
#endif
     }
}




static void callback_player_play_pause(Eloquence_Face *face, 
		Evas_Object *obj, const char *emission, const char *source){
   switch (face->conf->player)
     {
#ifdef HAVE_XMMS_XMMSCTRL_H
      case PLAYER_XMMS:
         xmms_control_play_pause(face);
         break;	      
#endif
#ifdef HAVE_XMMSCLIENT_XMMSCLIENT_H
      case PLAYER_XMMS2:
				 xmms2_control_play_pause(face);
         break;              
#endif
#ifdef HAVE_BMP_BEEPCTRL_H
      case PLAYER_BMP:
         bmp_control_play_pause(face);
         break;	      
#endif
#ifdef HAVE_BMPX_METADATA_H
      case PLAYER_BMPX:
         bmpx_control_play_pause(face);
         break;	      
#endif
#ifdef HAVE_AUDACIOUS_BEEPCTRL_H
      case PLAYER_AUDACIOUS:
         audacious_control_play_pause(face);
         break;	      
#endif
#ifdef HAVE_AMAROK
      case PLAYER_AMAROK:
         amarok_control_play_pause(face);
         break;	      
#endif
#ifdef HAVE_LIBMPD_LIBMPDCLIENT_H
      case PLAYER_MPD:
	 mpd_control_play_pause(face);
         break;              
#endif
     }

}




static void callback_player_track_next(Eloquence_Face *face, 
		Evas_Object *obj, const char *emission, const char *source){
   switch (face->conf->player)
     {
#ifdef HAVE_XMMS_XMMSCTRL_H
      case PLAYER_XMMS:
         xmms_control_track_next(face);
         break;	      
#endif
#ifdef HAVE_XMMSCLIENT_XMMSCLIENT_H
      case PLAYER_XMMS2:
				xmms2_control_track_next(face);
				break;              
#endif
#ifdef HAVE_BMP_BEEPCTRL_H
      case PLAYER_BMP:
         bmp_control_track_next(face);
         break;	      
#endif
#ifdef HAVE_BMPX_METADATA_H
      case PLAYER_BMPX:
         bmpx_control_track_next(face);
         break;	      
#endif
#ifdef HAVE_AUDACIOUS_BEEPCTRL_H
      case PLAYER_AUDACIOUS:
         audacious_control_track_next(face);
         break;	      
#endif
#ifdef HAVE_AMAROK
      case PLAYER_AMAROK:
         amarok_control_track_next(face);
         break;	      
#endif
#ifdef HAVE_LIBMPD_LIBMPDCLIENT_H
      case PLAYER_MPD:
	 mpd_control_track_next(face);
         break;              
#endif
     }
	
}




static void callback_player_track_prev(Eloquence_Face *face, 
		Evas_Object *obj, const char *emission, const char *source){
   switch (face->conf->player)
     {
#ifdef HAVE_XMMS_XMMSCTRL_H
      case PLAYER_XMMS:
         xmms_control_track_prev(face);
         break;	      
#endif
#ifdef HAVE_XMMSCLIENT_XMMSCLIENT_H
      case PLAYER_XMMS2:
				xmms2_control_track_prev(face);
				break;              
#endif
#ifdef HAVE_BMP_BEEPCTRL_H
      case PLAYER_BMP:
         bmp_control_track_prev(face);
         break;	      
#endif
#ifdef HAVE_BMPX_METADATA_H
      case PLAYER_BMPX:
         bmpx_control_track_prev(face);
         break;	      
#endif
#ifdef HAVE_AUDACIOUS_BEEPCTRL_H
      case PLAYER_AUDACIOUS:
         audacious_control_track_prev(face);
         break;	      
#endif
#ifdef HAVE_AMAROK
      case PLAYER_AMAROK:
         amarok_control_track_prev(face);
         break;	      
#endif
#ifdef HAVE_LIBMPD_LIBMPDCLIENT_H
      case PLAYER_MPD:
	 mpd_control_track_prev(face);
         break;              
#endif
     }
	
}




static void callback_player_vol_inc(Eloquence_Face *face, 
		Evas_Object *obj, const char *emission, const char *source){
   switch (face->conf->player)
     {
#ifdef HAVE_XMMS_XMMSCTRL_H
      case PLAYER_XMMS:
         xmms_control_vol_inc(face);
         break;	      
#endif
#ifdef HAVE_XMMSCLIENT_XMMSCLIENT_H
      case PLAYER_XMMS2:
	 /* xmms2 doesn't yet support this */
         break;              
#endif
#ifdef HAVE_BMP_BEEPCTRL_H
      case PLAYER_BMP:
         bmp_control_vol_inc(face);
         break;	      
#endif
#ifdef HAVE_BMPX_METADATA_H
      case PLAYER_BMPX:
         bmpx_control_vol_inc(face);
         break;	      
#endif
#ifdef HAVE_AUDACIOUS_BEEPCTRL_H
      case PLAYER_AUDACIOUS:
         audacious_control_vol_inc(face);
         break;	      
#endif
#ifdef HAVE_AMAROK
      case PLAYER_AMAROK:
         amarok_control_vol_inc(face);
         break;	      
#endif
#ifdef HAVE_LIBMPD_LIBMPDCLIENT_H
      case PLAYER_MPD:
	 mpd_control_vol_inc(face);
         break;              
#endif
     }

}




static void callback_player_vol_dec(Eloquence_Face *face, 
		Evas_Object *obj, const char *emission, const char *source){
   switch (face->conf->player)
     {
#ifdef HAVE_XMMS_XMMSCTRL_H
      case PLAYER_XMMS:
         xmms_control_vol_dec(face);
         break;	      
#endif
#ifdef HAVE_XMMSCLIENT_XMMSCLIENT_H
      case PLAYER_XMMS2:
	 /* xmms2 doesn't yet support this */
         break;              
#endif
#ifdef HAVE_BMP_BEEPCTRL_H
      case PLAYER_BMP:
         bmp_control_vol_dec(face);
         break;	      
#endif
#ifdef HAVE_BMPX_METADATA_H
      case PLAYER_BMPX:
         bmpx_control_vol_dec(face);
         break;	      
#endif
#ifdef HAVE_AUDACIOUS_BEEPCTRL_H
      case PLAYER_AUDACIOUS:
         audacious_control_vol_dec(face);
         break;	      
#endif
#ifdef HAVE_AMAROK
      case PLAYER_AMAROK:
         amarok_control_vol_dec(face);
         break;	      
#endif
#ifdef HAVE_LIBMPD_LIBMPDCLIENT_H
      case PLAYER_MPD:
	 mpd_control_vol_dec(face);
         break;              
#endif
     }
	
}




static void callback_player_shuffle(Eloquence_Face *face, 
		Evas_Object *obj, const char *emission, const char *source){
   switch (face->conf->player)
     {
#ifdef HAVE_XMMS_XMMSCTRL_H
      case PLAYER_XMMS:
         xmms_control_shuffle(face);
         break;	      
#endif
#ifdef HAVE_BMP_BEEPCTRL_H
      case PLAYER_BMP:
/*  disabled because crashing bmp, bad bug in bmp!!!
	bmp_control_shuffle(face);
*/
         break;	      
#endif
#ifdef HAVE_BMPX_METADATA_H
      case PLAYER_BMPX:
	bmpx_control_shuffle(face);
         break;	      
#endif
#ifdef HAVE_XMMSCLIENT_XMMSCLIENT_H
      case PLAYER_XMMS2:
	 xmms2_control_shuffle(face);
         break;
#endif
#ifdef HAVE_AUDACIOUS_BEEPCTRL_H
      case PLAYER_AUDACIOUS:
/*  disabled because crashing Audacious, bad bug in Audacious!!!
         audacious_control_shuffle(face);
*/
         break;	      
#endif
#ifdef HAVE_AMAROK
      case PLAYER_AMAROK:
         amarok_control_shuffle(face);
         break;	      
#endif
#ifdef HAVE_LIBMPD_LIBMPDCLIENT_H
      case PLAYER_MPD:
	 mpd_control_shuffle(face);
         break;              
#endif
     }

}




static void
_button_cb_mouse_down(void *data, Evas *e, Evas_Object *obj, void *event_info) {
		Instance *inst;
		Evas_Event_Mouse_Down *ev;
   
   	inst = data;
   	ev = event_info;
   	if ((ev->button == 1)) {
				int cx, cy, cw, ch;
				e_gadcon_canvas_zone_geometry_get(inst->gcc->gadcon,
								&cx, &cy, &cw, &ch);
				e_menu_activate_mouse(inst->main_menu,
								e_util_zone_current_get(e_manager_current_get()),
								cx + ev->output.x, cy + ev->output.y, 1, 1,
								E_MENU_POP_DIRECTION_DOWN, ev->timestamp);
				evas_event_feed_mouse_up(inst->gcc->gadcon->evas, ev->button,
								EVAS_BUTTON_NONE, ev->timestamp, NULL);
		}
}
static void
_menu_cb_post(void *data, E_Menu *m) {
}

static void callback_gui_menu(Eloquence_Face *face, Evas_Object *obj, 
				const char *emission, const char *source) {

		Evas_Event_Mouse_Down *ev;
		int cx, cy, cw, ch;
		e_gadcon_canvas_zone_geometry_get(face->inst->gcc->gadcon,
						&cx, &cy, &cw, &ch);
		e_menu_activate_mouse(face->menu,
			      e_util_zone_current_get(e_manager_current_get()),
			      cx + ev->output.x, cy + ev->output.y, 1, 1,
			      E_MENU_POP_DIRECTION_DOWN, ev->timestamp);
		evas_event_feed_mouse_up(face->inst->gcc->gadcon->evas, ev->button,
						EVAS_BUTTON_NONE, ev->timestamp, NULL);
		
}



# define D(x)  do {printf(__FILE__ ":%d:  ", __LINE__); printf x; fflush(stdout);} while (0)
/* module setup */
EAPI E_Module_Api e_modapi = {
   E_MODULE_API_VERSION,
     "Eloquence"
};

EAPI void *
e_modapi_init(E_Module *m) {

D(("modapi init\n"));
  
   // check module api version 
   if (m->api->version < E_MODULE_API_VERSION) {
/*			 
			 	e_error_dialog_show(_("Module API Error"),
								_("Error initializing Module: Eloquence\n"
									"It requires a minimum module API version of: %i.\n"
									"The module API advertized by Enlightenment is: %i.\n"
									"Aborting module."),
								E_MODULE_API_VERSION,
								m->api->version);
				return NULL;
*/				
	 }

	 eloquence_module = m;
   
   e_gadcon_provider_register(&_gadcon_class);
   return 1;
}

EAPI int
e_modapi_shutdown(E_Module *m) {
		D(("modapi shutdown\n"));
		Eloquence *eloquence;
		eloquence_module = m->data;
		eloquence_module = NULL;
		e_gadcon_provider_unregister(&_gadcon_class);
		return 1;
}

EAPI int
e_modapi_save(E_Module *m){
   return 1;
}

EAPI int
e_modapi_about(E_Module *m) {
   e_module_dialog_show(m,_("Eloquence"),
			_("Music Player Remote Control"));
   return 1;
}


